package com.ejlchina.tool.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doAfterTextChanged
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.adolf.androiddemo.R
import com.adolf.androiddemo.databinding.DialogIndexFixSelectIndexBinding
import com.adolf.androiddemo.databinding.FragmentPushRodParametersBinding
import com.huyuhui.fastble.data.BleDevice
import com.ejlchina.tool.adapter.AntiPinchBottomDialogAdapter
import com.ejlchina.tool.adapter.DeviceAdapterRadio
import com.ejlchina.tool.adapter.IndexFixDialogAdapter
import com.ejlchina.tool.base.BaseBindingFragment2
import com.ejlchina.tool.bean.BleDeviceBean
import com.ejlchina.tool.bean.PushRodBean
import com.ejlchina.tool.enums.AntiPinchModeEnum
import com.ejlchina.tool.enums.OnOffEnum
import com.ejlchina.tool.enums.RotateDirectionEnum
import com.ejlchina.tool.enums.SuccessFailEnum
import com.ejlchina.tool.singleton.GlobalConnectObject
import com.ejlchina.tool.util.COMMAND_ELECTRICAL_MACHINERY_SET_UPWARD
import com.ejlchina.tool.util.COMMAND_ELECTRICAL_MACHINERY_UPWARD
import com.ejlchina.tool.util.COMMAND_GET_ELECTRICAL_MACHINERY_DOWNWARD
import com.ejlchina.tool.util.COMMAND_SET_ELECTRICAL_MACHINERY_DOWNWARD
import com.ejlchina.tool.util.bytearray.intTo16HexStringLE
import com.ejlchina.tool.util.bytearray.intTo32HexStringLE
import com.ejlchina.tool.util.bytearray.intToByteHexString
import com.ejlchina.tool.util.bytearray.readByteArrayLE
import com.ejlchina.tool.util.bytearray.toHexString
import com.ejlchina.tool.util.getIntFromByteArray
import com.ejlchina.tool.util.showToast
import com.ejlchina.tool.view.GridItemDecoration
import com.google.android.material.bottomsheet.BottomSheetDialog

class PushRodParametersFragment: BaseBindingFragment2<FragmentPushRodParametersBinding>() {

    private val pushRodBean = PushRodBean()
    private val machineAntiPinchArray = arrayListOf(AntiPinchModeEnum.NO_ANTI_PINCH,AntiPinchModeEnum.OPEN_ANTI_PINCH,AntiPinchModeEnum.CLOSE_ANTO_PINCH)
    private val closeDoorSection = arrayListOf(1,2,3)
    override fun getViewBinding(inflater: LayoutInflater, container: ViewGroup): FragmentPushRodParametersBinding {
        return FragmentPushRodParametersBinding.inflate(inflater,container,true)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()
        initData()
    }

    private fun initViews(){
        setHeadTitle("推杆参数")
        setRightIconVisibility(View.GONE)
        initListeners()
    }

    private fun initData(){
        initDevices()
    }

    private fun initListeners(){
        binding.includeAntiPinch.radioGroup.setOnCheckedChangeListener { group, checkedId ->
            when (checkedId) {
                R.id.rb_cw -> pushRodBean.rotateDirection = RotateDirectionEnum.CW
                R.id.rb_ccw -> pushRodBean.rotateDirection = RotateDirectionEnum.CCW
            }
        }

        binding.includeAntiPinch.antiPinchRadioGroup.setOnCheckedChangeListener { group, checkedId ->
            when(checkedId){
                R.id.rb_anti_pinch_on -> pushRodBean.machineAntiPinch = AntiPinchModeEnum.CLOSE_ANTO_PINCH
                R.id.rb_anti_pinch_off -> pushRodBean.machineAntiPinch = AntiPinchModeEnum.NO_ANTI_PINCH
            }
        }
//        binding.includeAntiPinch.layoutMachineAntiPinch.setOnClickListener {
//            setAntiPinchBottom(pushRodBean.machineAntiPinch) {
//                pushRodBean.machineAntiPinch = it
//                binding.includeAntiPinch.tvMachineAntiPinch.text =  it.info
//            }
//        }

        binding.includeDoorSection.tvCloseDoorSectionCount.setOnClickListener {
            showCloseCountBottom{
                binding.includeDoorSection.tvCloseDoorSectionCount.text = it.toString()
                binding.includeDoorSection.layoutIntervalTime.visibility = if (it == 1) View.GONE else View.VISIBLE
                if (it == 1){
                    pushRodBean.closeSectionDelay = 0
                    binding.includeDoorSection.etInterval.setText(pushRodBean.closeSectionDelay.toString())
                }
                pushRodBean.closeSectionCount = it
            }
        }

        binding.btnConfirm.setOnClickListener {
            setPushRodData(deviceAdapter.getSelectDevice())
        }

        binding.includeDoorSection.etEveryTravelTime.doAfterTextChanged {
            it?.let {
                if (it.isNotEmpty()){
                    pushRodBean.closeSectionDuration = it.toString().toInt()
                }
            }
        }

        binding.includeDoorSection.etCloseDelay.doAfterTextChanged {
            it?.let {
                if (it.isNotEmpty()){
                    pushRodBean.autoCloseDelay = it.toString().toInt()
                }
            }
        }
        binding.includeDoorSection.etInterval.doAfterTextChanged {
            it?.let {
                if (it.isNotEmpty()){
                    pushRodBean.closeSectionDelay = it.toString().toInt()
                }
            }
        }
    }

    private fun showCloseCountBottom(clickCallback: (Int) -> Unit){

        val indexFixDialogAdapter = IndexFixDialogAdapter(closeDoorSection,pushRodBean.closeSectionCount)
        val layoutBinding = DialogIndexFixSelectIndexBinding.inflate(LayoutInflater.from(binding.root.context),null,false)
        val bottomSheetDialog = BottomSheetDialog(binding.root.context, R.style.bottom_sheet_dialog)
        layoutBinding.recyclerView.apply {
            adapter = indexFixDialogAdapter
            layoutManager = LinearLayoutManager(binding.root.context)
        }
        layoutBinding.tvCancel.setOnClickListener {
            bottomSheetDialog.dismiss()
        }
        layoutBinding.tvConfirm.setOnClickListener {
            clickCallback(indexFixDialogAdapter.getSelectIndex())
            bottomSheetDialog.dismiss()
        }
        bottomSheetDialog.setContentView(layoutBinding.root)
        bottomSheetDialog.show()
    }

    private fun setAntiPinchBottom(selectMode: AntiPinchModeEnum,clickCallback: (AntiPinchModeEnum) -> Unit){
        val indexFixDialogAdapter = AntiPinchBottomDialogAdapter(machineAntiPinchArray,selectMode)
        val layoutBinding = DialogIndexFixSelectIndexBinding.inflate(LayoutInflater.from(binding.root.context),null,false)
        val bottomSheetDialog = BottomSheetDialog(binding.root.context, R.style.bottom_sheet_dialog)
        layoutBinding.recyclerView.apply {
            adapter = indexFixDialogAdapter
            layoutManager = LinearLayoutManager(binding.root.context)
        }
        layoutBinding.tvCancel.setOnClickListener {
            bottomSheetDialog.dismiss()
        }
        layoutBinding.tvConfirm.setOnClickListener {
            clickCallback(indexFixDialogAdapter.getSelectMode())
            bottomSheetDialog.dismiss()
        }
        bottomSheetDialog.setContentView(layoutBinding.root)
        bottomSheetDialog.show()
    }

    override fun whenReceiveCommand(bleDevice: BleDeviceBean,command: String, commandByteArray: ByteArray) {
        super.whenReceiveCommand(bleDevice,command, commandByteArray)
        when (command){
            COMMAND_ELECTRICAL_MACHINERY_UPWARD -> {
                setPushBeanData(commandByteArray)
                setUIData()
            }
            COMMAND_ELECTRICAL_MACHINERY_SET_UPWARD -> {
                if (commandByteArray[commandByteArray.size - 1].toInt() == SuccessFailEnum.SUCCESS.value){
                    deviceAdapter.getSelectDevice().isMachineAntiPinchOn = commandByteArray[0].toInt() == OnOffEnum.ON.value
                }
                setResultToast(commandByteArray[commandByteArray.size - 1].toInt())
            }
        }
        dismissLoading()
    }


    private fun setPushBeanData(byteArray: ByteArray){
        when(byteArray[0].toInt()){
            0 -> pushRodBean.machineAntiPinch = AntiPinchModeEnum.NO_ANTI_PINCH
            else -> pushRodBean.machineAntiPinch = AntiPinchModeEnum.CLOSE_ANTO_PINCH

        }
        pushRodBean.electricAntiPinch = OnOffEnum.getFromIndex(byteArray[1].toInt())
        when(byteArray[2].toInt()){
            0 -> pushRodBean.rotateDirection = RotateDirectionEnum.CW
            1 -> pushRodBean.rotateDirection = RotateDirectionEnum.CCW
        }
        pushRodBean.autoCloseDelay = getIntFromByteArray(byteArray.readByteArrayLE(3,4)) / 1000
        pushRodBean.closeSectionCount = byteArray[7].toInt()
        pushRodBean.closeSectionDuration = getIntFromByteArray(byteArray.readByteArrayLE(8,4)) / 1000
        pushRodBean.closeSectionDelay = getIntFromByteArray(byteArray.readByteArrayLE(20,4)) / 1000
    }
    override fun whenDeviceDisConnect(disConnectDevice: BleDevice) {
        super.whenDeviceDisConnect(disConnectDevice)

    }

    private fun setUIData(){
        checkAntiPinchRadioButton(pushRodBean.machineAntiPinch.index)
        checkRadioButton(pushRodBean.rotateDirection.index)
        binding.includeDoorSection.etCloseDelay.setText(pushRodBean.autoCloseDelay.toString())
        binding.includeDoorSection.tvCloseDoorSectionCount.text = pushRodBean.closeSectionCount.toString()
        val isCloseDoorSectionSettingVisible = pushRodBean.closeSectionCount > 1
        binding.includeDoorSection.layoutIntervalTime.visibility = if (isCloseDoorSectionSettingVisible) View.VISIBLE else View.GONE
        binding.includeDoorSection.etEveryTravelTime.setText(pushRodBean.closeSectionDuration.toString())
        binding.includeDoorSection.etInterval.setText(pushRodBean.closeSectionDelay.toString())
    }

    private fun checkRadioButton(index: Int){
        val id = when(index){
            0 -> binding.includeAntiPinch.rbCw.id
            else -> binding.includeAntiPinch.rbCcw.id
        }
        binding.includeAntiPinch.radioGroup.check(id)
    }

    private fun checkAntiPinchRadioButton(index: Int){
        val checkId = when(index){
            0 -> binding.includeAntiPinch.rbAntiPinchOff.id
            else -> binding.includeAntiPinch.rbAntiPinchOn.id
        }
        binding.includeAntiPinch.antiPinchRadioGroup.check(checkId)
    }

    private fun getPushRodData(bleDevice: BleDeviceBean){
        getCommandData(bleDevice,COMMAND_GET_ELECTRICAL_MACHINERY_DOWNWARD)
    }
    private fun initDevices(){
        deviceAdapter = DeviceAdapterRadio(GlobalConnectObject.getCurrentConnectDeviceList()){
            getPushRodData(it)
        }
        binding.rvDevices.apply {
            adapter = deviceAdapter
            layoutManager = GridLayoutManager(requireContext(),3)
            if (itemDecorationCount == 0){
                addItemDecoration(GridItemDecoration(3,11,11))
            }
        }
    }



    private fun setPushRodData(bleDevice: BleDeviceBean){
        if (!checkInputData()) return

        val commandStringBuffer = StringBuffer()
        commandStringBuffer.append(pushRodBean.machineAntiPinch.index.toHexString())
        commandStringBuffer.append(pushRodBean.electricAntiPinch.value.toHexString())
        commandStringBuffer.append(pushRodBean.rotateDirection.index.toHexString())
        commandStringBuffer.append(intTo32HexStringLE(pushRodBean.autoCloseDelay * 1000))
        commandStringBuffer.append(intToByteHexString(pushRodBean.closeSectionCount))
        setCloseSectionDuration(commandStringBuffer)
        setCloseSectionDelay(commandStringBuffer)
        setCommandData(bleDevice,COMMAND_SET_ELECTRICAL_MACHINERY_DOWNWARD,commandStringBuffer.toString())
    }

    private fun checkInputData(): Boolean {
        val closeDelayTime = binding.includeDoorSection.etCloseDelay.text.toString()
        val everyTravelTime = binding.includeDoorSection.etEveryTravelTime.text.toString()
        val intervalTime = binding.includeDoorSection.etInterval.text.toString()
        if (closeDelayTime.isEmpty()) {
            showToast("请输入关门延迟时间")
            return false
        }

        if (closeDelayTime.toInt() < 5 || closeDelayTime.toInt() > 300) {
            showToast("关门延迟时间应该在5到300秒之间")
            return false
        }


        if (everyTravelTime.isEmpty()) {
            showToast("请输入每段行程时间")
            return false
        }
        if (everyTravelTime.toInt() <= 0 || everyTravelTime.toInt() > 99) {
            showToast("每段行程时间应该在1到99秒之间")
            return false
        }
        if (intervalTime.isEmpty()) {
            showToast("请输入间隔等待时间")
            return false
        }

        if (intervalTime.toInt() > 99) {
            showToast("间隔等待时间应该在0到99秒之间")
            return false
        }
        return true
    }

    private fun coverString(stringBuffer: StringBuffer){
        stringBuffer.append(intTo32HexStringLE(0))
    }

    private fun setCloseSectionDuration(stringBuffer: StringBuffer){
        val closeSectionCount = pushRodBean.closeSectionCount
        for (item in 1 ..closeSectionCount){
            stringBuffer.append(intTo32HexStringLE(pushRodBean.closeSectionDuration * 1000))
        }
        for (item in closeSectionCount until 3){
            coverString(stringBuffer)
        }
    }

    private fun setCloseSectionDelay(stringBuffer: StringBuffer){
        for (item in 1 ..2){
            stringBuffer.append(intTo32HexStringLE(pushRodBean.closeSectionDelay * 1000))
        }
    }
}